package com.qf.osmproduct.product.service.impl;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.qf.api.recharge.feign.RechargeFeignService;
import com.qf.common.core.entity.UserSearchHistory;
import com.qf.common.core.entity.product.Category;
import com.qf.common.core.entity.product.Product;
import com.qf.common.core.entity.product.ProductBanner;
import com.qf.common.core.entity.product.Review;
import com.qf.common.core.entity.shop.Shop;
import com.qf.common.core.util.UserUtils;
import com.qf.osmproduct.product.mapper.*;
import com.qf.osmproduct.product.param.HomeGoodsParam;
import com.qf.osmproduct.product.param.ProductParam;
import com.qf.osmproduct.product.service.ProductService;
import com.qf.osmproduct.product.vo.GoodsVO;
import com.qf.osmproduct.product.vo.HomeRECVO;
import com.qf.osmproduct.review.mapper.ReviewMapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;


/**
 * @author GaoQiangLiang
 */
@Service
public class ProductServiceImpl implements ProductService {


    @Resource
    private ProductMapper productMapper;

    @Resource
    private ProductCategoryMapper productCategoryMapper;

    @Resource
    private UserSearchHistoryMapper userSearchHistoryMapper;


    @Resource
    private ReviewMapper reviewMapper;


    @Resource
    private ProductBannerMapper productBannerMapper;


    @Resource
    private RechargeFeignService rechargeFeignService;

    @Resource
    private ShopMapper shopMapper;


    /**
     * 获取首页商品列表，需要按照分类进行展示
     *
     * @param homeGoodsParam 商品参数
     * @return 商品列表
     */
    @Override
    public List<Tree<String>> getList(HomeGoodsParam homeGoodsParam) {
        // 查询所有的商品分类
        List<Category> categoryList = productCategoryMapper.selectList(null);
        // 构建树结构
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        // 找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.build(categoryList, "0", treeNodeConfig, (treeNode, tree) -> {
            // 主键需要留着
            tree.setId(treeNode.getCategoryId().toString());
            // 其他字段,需要自定义设置
            tree.setParentId(treeNode.getParentId().toString());
            tree.setName(treeNode.getCategoryName());
            tree.putExtra("category_image_src", treeNode.getCategoryImageSrc());
            tree.putExtra("create_time", simpleDateFormat.format(treeNode.getCreateTime()));
        });
        return treeNodes;
    }


    /**
     * 获取首页推荐商品
     *
     * @return 首页推荐商品
     */
    @Override
    public HomeRECVO getHomeREC() {
        // 获取商品表中推荐商品
        List<Product> recommendList = productMapper.selectList(Wrappers.<Product>lambdaQuery().isNotNull(Product::getProductBanner));
        // 封装返回值
        HomeRECVO homeRECVO = new HomeRECVO();
        List<String> bannersList = new ArrayList<>();
        // 将轮播图封装到List<String> bannerList中
        for (Product product : recommendList) {
            bannersList.add(product.getProductBanner());
        }
        // 设置轮播图和推荐的商品对象
        homeRECVO.setHomeRecList(recommendList);
        homeRECVO.setBanners(bannersList);
        return homeRECVO;

    }

    /**
     * 根据商品类型获取首页展示的商品
     *
     * @param homeGoodsParam 商品参数
     * @return 商品列表
     */
    @Override
    public List<Product> getHomeShowGoods(HomeGoodsParam homeGoodsParam) {
        // 根据商品类型进行查询：product_sortType 0:流行、1：新款、2：精选
        Integer productSortType = 0;

        // 根据商品类型进行查询
        if (homeGoodsParam.getSortType().equals("syn")) {
            productSortType = 0;
        } else if (homeGoodsParam.getSortType().equals("new")) {
            productSortType = 1;
        } else {
            productSortType = 2;
        }
        List<Product> productList = productMapper.selectList(Wrappers.<Product>lambdaQuery().eq(Product::getProductSortType, productSortType));
        return productList;
    }


    /**
     * 获取搜索热词
     *
     * @return 搜索热词列表
     */
    @Override
    public List<String> getHotProductName() {
        // 根据销量进行降序排序，取前10条热搜商品的名称
        List<String> hotProductName = productMapper.selectList(Wrappers.<Product>lambdaQuery()
                        .orderByDesc(Product::getProductSaleCount))
                .stream()
                .limit(10)
                .map(Product::getProductName)
                .collect(Collectors.toList());
        return hotProductName;
        /*

         */
    }


    /**
     * 搜索商品
     *
     * @param productParam 商品参数
     * @return 商品列表
     */
    @Override
    public List<Product> searchProduct(ProductParam productParam) {
        /**
         * 搜索商品的步骤：
         * 1. 根据用户输入的关键词是否为空，进行判断
         * 2. 如果关键字为空，则用户搜索记录表中前10条记录获取关键字进行搜索，这里需要按照时间顺序进行排序
         * 3. 根据关键字进行模糊搜索，这里的关键词是查询出来的关键词列表
         * 4. 否则，关键字不为空，则按照用户输入的关键字进行模糊搜索
         * 5. 将搜索记录保存到数据库中
         */
        // 1. 根据用户输入的关键词是否为空，进行判断
        if (productParam.getGoodsName() == null || productParam.getGoodsName().trim().equals("")) {
            // 2. 如果关键字为空，则用户搜索记录表中前10条记录获取关键字进行搜索，这里需要按照时间顺序进行降序排序
            List<String> keywordList = userSearchHistoryMapper.selectList(Wrappers.<UserSearchHistory>lambdaQuery()
                            .eq(UserSearchHistory::getUserId, UserUtils.getUid())
                            .eq(UserSearchHistory::getIsDeleted, 0)
                            .orderByDesc(UserSearchHistory::getSearchTime))
                    .stream()
                    .map(UserSearchHistory::getSearchKeyword)
                    .limit(10)
                    .collect(Collectors.toList());

            // 3. 构建多关键词模糊查询条件
            if (!keywordList.isEmpty()) {
                List<Product> productList = productMapper.selectList(Wrappers.<Product>lambdaQuery()
                        .apply(keywordList.stream()
                                .map(keyword -> "product_name LIKE '%" + keyword + "%'")
                                .collect(Collectors.joining(" OR ")))
                        .orderByDesc(Product::getProductSaleCount)
                        .first("LIMIT 100"));

                return productList;
            } else {
                // 如果没有热搜词，默认按销量取前100个商品
                return productMapper.selectList(Wrappers.<Product>lambdaQuery()
                                .orderByDesc(Product::getProductSaleCount))
                        .stream()
                        .limit(100)
                        .collect(Collectors.toList());
            }
        } else {
            // 4. 否则，关键字不为空，则按照用户输入的关键字进行模糊搜索
            List<Product> productList = productMapper.selectList(Wrappers.<Product>lambdaQuery()
                    .like(Product::getProductName, productParam.getGoodsName()));
            // 5. 将搜索记录保存到数据库中
            UserSearchHistory userSearchHistory = new UserSearchHistory();
            userSearchHistory.setUserId(Long.valueOf(UserUtils.getUid()));
            userSearchHistory.setSearchKeyword(productParam.getGoodsName());
            userSearchHistory.setSearchTime(new java.util.Date());
            userSearchHistoryMapper.insert(userSearchHistory);
            return productList;
        }
    }


    /**
     * 根据商品id获取商品详情信息
     *
     * @param productId 商品id
     * @return 商品详情信息
     */
    @Override
    public GoodsVO getProductById(Integer productId) {
        /**
         * 1. 首选根据商品id查询商品详情信息
         * 2.
         */

        // 1. 根据商品id查询商品详情信息
        Product product = productMapper.selectOne(Wrappers.lambdaQuery(Product.class).eq(Product::getProductId, productId));

        GoodsVO goodsVO = new GoodsVO();

        // 封装到商品信息
        goodsVO.setProduct(product);

        // 2. 根据商品id查询商品的轮播图信息
        List<String> productBannerList = productBannerMapper.selectList(Wrappers.lambdaQuery(ProductBanner.class)
                .eq(ProductBanner::getProductimageProductId, productId))
                .stream()
                .map(ProductBanner::getProductimageSrc)
                .collect(Collectors.toList());

        // 封装到商品的轮播图信息
        goodsVO.setBannersList(productBannerList);

        // 3. 根据商品id查询店铺id，然后查询店铺信息
        Integer shopId = productMapper.selectOne(Wrappers.lambdaQuery(Product.class).eq(Product::getProductId, productId)).getProductShopId();
        // 根据店铺id查询店铺信息
        Shop shopInfo = shopMapper.selectOne(Wrappers.lambdaQuery(Shop.class).eq(Shop::getShopId, shopId));

        // 封装到商品的店铺信息
        goodsVO.setShopInfo(shopInfo);


        // 4. 获取商品的评论信息进行封装，根据商品id查询商品的评论信息
        List<Review> reviewsList = reviewMapper.selectList(Wrappers.lambdaQuery(Review.class)
                .eq(Review::getReviewProductId, productId));

        // 根据商品id从评论表中获得评论的用户id，然后在从用户表查询用户的头像进行封装
        List<Integer> userIdList = reviewsList.stream().map(Review::getReviewUserId).collect(Collectors.toList());
        // 然后获取用户的头像列表信息
        List<String> userAvatarsList = rechargeFeignService.getAvatarsByUserIds(userIdList);
        // 封装用户的头像信息
        goodsVO.setUserAvatarsList(userAvatarsList);
        // 封装评论信息
        goodsVO.setReviewsList(reviewsList);
        return goodsVO;
    }



    /**
     * 根据商品id列表获取商品信息
     *
     * @param productIds 商品id列表
     * @return 商品信息列表
     */
    @Override
    public List<Product> getProductInfo(List<Integer> productIds) {
        if (productIds != null && !productIds.isEmpty()) {
            return productMapper.selectList(Wrappers.lambdaQuery(Product.class)
                    .in(Product::getProductId, productIds));
        }
        return Collections.emptyList();
    }
}
